#ifndef __EVENT_REGIST_CENTER__
#define __EVENT_REGIST_CENTER__

#include <vector>
#include <unordered_map>
#include "EventTypes.h"
#include <atomic>
#include <mutex>
#include <function>

typedef struct 
{
    /* data */
    void *params = nullptr;
    /* event mgr class point */
    void *mgr = nullptr;
    /* event */
    EventType even = EVE_NULL;
}postData;

class EvenProcBase;

class EventCenter
{
    EventCenter(){}
public:
    static EventCenter* getInstance()
    {
        if(!mpInstance)
        {
            mpInstance = new EventCenter();
        }
        return mpInstance;
    }
    ~EventCenter(){}

public:
    bool register(EventType even, EvenProcBase* processor)
    {
        if(even > EVE_NULL && even < EVE_MAX)
        {
            std::lock_guard<std::mutex> lock(m_registLock);
            for (auto i : m_registEvenList[even])
            {
                if(i == processor)
                {
                    return false;
                }
            }
            m_registEvenList[even].push_back(processor);
            return true;
        }

        return false;
    }

    bool unregister(EventType even, EvenProcBase* processor)
    {
        if(even > EVE_NULL && even < EVE_MAX)
        {
            std::lock_guard<std::mutex> lock(m_registLock);
            for(auto i = m_registEvenList[even].begin(); i != m_registEvenList[even].end(); i++)
            {
                if (i == processor)
                {
                    m_registEvenList[even].earse(i);
                    return true;
                }
            }
        }

        return false;
    }


    bool receiveEven(EventType even, void* data)
    {
        bool ret = true;
        for(EvenProcBase* i : m_registEvenList[even])
        {
            ret = i->EvenProc(even, data) && ret;
        }

        return ret;
    }
    
private:
    static EventCenter *mpInstance;

private:
    std::mutex m_registLock;
    std::unordered_map<EventType, std::vector<EvenProcBase*>> m_registEvenList{};

};

EventCenter* EventCenter::mpInstance = NULL;

#endif